package com.aioz.security.service.impl;

import com.aioz.security.common.ResponseResult;
import com.aioz.security.entity.Application;
import com.aioz.security.entity.Company;
import com.aioz.security.entity.Interview;
import com.aioz.security.entity.Position;
import com.aioz.security.entity.vo.CensusAppVo;
import com.aioz.security.entity.vo.CensusCompanyVo;
import com.aioz.security.entity.vo.CensusInterVo;
import com.aioz.security.entity.vo.CensusPositionVo;
import com.aioz.security.service.CensusService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class CensusServiceImpl implements CensusService {

    @Resource
    private ApplicationServiceImpl applicationService;

    @Resource
    private PositionServiceImpl positionService;

    @Resource
    private InterviewServiceImpl interviewService;

    @Resource
    private CompanyServiceImpl companyService;

    @Resource
    private UserServiceImpl userService;


    @Override
    public ResponseResult censusApplyData(Integer companyId) {
        List<Application> applications = applicationService.query().eq("company_id", companyId).list();
        List<CensusAppVo> censusAppVos = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            CensusAppVo censusAppVo = new CensusAppVo();
            censusAppVo.setKey(i + "月");
            censusAppVo.setValue(computeValue(applications, i));
            censusAppVos.add(censusAppVo);
        }
        return new ResponseResult<>(200,censusAppVos);
    }

    @Override
    public ResponseResult censusPositionData(Integer companyId) {
        List<Position> positions = positionService.query().eq("company_id", companyId).list();
        List<CensusAppVo> censusAppVos = new ArrayList<>();
        for (Position position : positions) {
            CensusAppVo censusAppVo = new CensusAppVo();
            censusAppVo.setValue(position.getQuantity());
            censusAppVo.setKey(position.getTitle());
            censusAppVos.add(censusAppVo);
        }
        return new ResponseResult<>(200,censusAppVos);
    }

    @Override
    public ResponseResult censusInterviewData(Integer companyId) {
        // 使用自己的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(9);
        long startTime = System.currentTimeMillis();
        List<Interview> interviews = interviewService.query().eq("company_id", companyId).list();
        List<CensusInterVo> censusInterVos = new ArrayList<>();
        for (Interview interview : interviews) {
            CensusInterVo censusInterVo = new CensusInterVo();
            CompletableFuture<String> completableFuture01 = CompletableFuture.supplyAsync(()->{
                // 申请人
                return userService.getById(interview.getUserId()).getUserName();
            },threadPool);
            CompletableFuture<String> completableFuture02 = CompletableFuture.supplyAsync(()->{
                // 申请岗位
                return positionService.getById(interview.getPositionId()).getTitle();
            },threadPool);
            // 申请时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(interview.getTime());
            censusInterVo.setTime(calendar.get(Calendar.MONTH));
            // 申请人
            try {
                censusInterVo.setUser(completableFuture01.get());
                censusInterVo.setPosition(completableFuture02.get());
            } catch (Exception e) {
               return new ResponseResult<>(403,"服务异常");
            }
            // 申请进度
            censusInterVo.setState(interview.getStatus());
            censusInterVos.add(censusInterVo);
        }
        //关闭线程池
        threadPool.shutdown();
        //结束时间
        long endTime = System.currentTimeMillis();
        //打印
        log.info("程序运行时间{} ms" ,(endTime - startTime));
        return new ResponseResult<>(200,censusInterVos);
    }

    @Override
    public ResponseResult censusApplicationCounts() {
        long startTime = System.currentTimeMillis();
        List<Company> companies = companyService.query().orderByDesc("scale").list();
        companies = companies.stream().limit(5).collect(Collectors.toList());
        List<CensusCompanyVo> companyVos = new ArrayList<>();
        List<Application> applications = applicationService.query().list();
        for (Company company : companies) {
            for (int i = 1; i <=12; i++) {
                CensusCompanyVo companyVo = new CensusCompanyVo();
                int finalI = i;
                long ac = applications.stream()
                        .filter(application -> Objects.equals(application.getCompanyId(), company.getId()))
                        .filter(application -> application.getApplyTime().getMonthValue() == finalI)
                        .count();
                companyVo.setAc(ac);
                companyVo.setName(company.getName());
                companyVo.setMonth(i + "月");
                companyVos.add(companyVo);
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println(companyVos);
        System.out.println("程序耗时:    " + (endTime - startTime));
        return new ResponseResult<>(200,companyVos);
    }

    @Override
    public ResponseResult censusPositionStars() {
        List<Position> positions = positionService.query().orderByDesc("hits").list();
        List<CensusPositionVo> positionVos = new ArrayList<>();
        for (Position position : positions) {
            CensusPositionVo positionVo = new CensusPositionVo();
            positionVo.setName(position.getTitle());
            positionVo.setStar(position.getHits());
            positionVos.add(positionVo);
        }
        log.info("{} " ,positionVos);
        return new ResponseResult<>(200,positionVos);
    }

    public Integer computeValue(List<Application> applications,int month){
        return   Math.toIntExact(applications.stream()
                .filter(application -> application.getApplyTime().getMonthValue() == month)
                .count());
    }
}
